#!/usr/bin/env python
# -*- coding:utf-8 -*-
import json
from django.shortcuts import render, HttpResponse
from django.http import JsonResponse
from django.views import View
from django.forms import model_to_dict
from django.views.decorators.csrf import csrf_exempt
from django.urls import reverse
from django.http import StreamingHttpResponse, FileResponse
from web import models
from web.forms.file import FolderModelForm
import requests
from utils.tencent.cos import CosBucket


# http://127.0.0.1:8002/manage/1/file/
# http://127.0.0.1:8002/manage/1/file/?folder=1
class File(View):

    def dispatch(self, request, *args, **kwargs):
        self.parent_object = None
        folder_id = request.GET.get('folder', "")  # 没值则为空
        if folder_id.isdecimal():  # 需要是十进制的数字
            self.parent_object = models.FileRepository.objects.filter(id=int(folder_id), file_type=2,
                                                                      project=request.tracer.project).first()
        return super().dispatch(request, *args, **kwargs)

    def get(self, request, project_id):

        # 文件列表
        queryset = models.FileRepository.objects.filter(project=request.tracer.project)
        parent_object = self.parent_object
        if parent_object:
            file_object_list = queryset.filter(parent=parent_object).order_by('-file_type')
        else:
            file_object_list = queryset.filter(parent__isnull=True).order_by('-file_type')

        # 导航条
        breadcrumb_list = []
        parent = parent_object
        while parent:
            breadcrumb_list.insert(0, model_to_dict(parent, ['id', 'name']))
            parent = parent.parent

        form = FolderModelForm(request, self.parent_object)
        context = {
            'form': form,
            'file_object_list': file_object_list,
            'breadcrumb_list': breadcrumb_list,
            'folder_id': parent_object
        }
        return render(request, 'file.html', context)

    def post(self, request, project_id):
        fid = request.POST.get('fid')
        edit_object = None
        if fid.isdecimal():
            # 修改
            edit_object = models.FileRepository.objects.filter(id=int(fid), file_type=2,
                                                               project=request.tracer.project).first()

        if edit_object:
            form = FolderModelForm(request, self.parent_object, data=request.POST, instance=edit_object)

        else:
            form = FolderModelForm(request, self.parent_object, data=request.POST)

        if form.is_valid():
            form.instance.project = request.tracer.project
            form.instance.file_type = 2
            form.instance.update_user = request.tracer.user
            form.instance.parent = self.parent_object
            form.save()
            return JsonResponse({'status': True})

        return JsonResponse({'status': False, 'error': form.errors})


def file_delete(request, project_id):
    """ 删除文件 """
    fid = request.GET.get('fid')

    # 删除数据库中的文件 & 文件夹 （级联删除）
    delete_object = models.FileRepository.objects.filter(id=fid, project=request.tracer.project).first()
    if delete_object.file_type == 1:
        # 删除文件（数据库文件删除、cos文件删除、项目已使用空间容量还回去）
        request.tracer.project.use_space -= delete_object.file_size
        request.tracer.project.save()

        # cos删除
        CosBucket.delete_file(request.tracer.project.bucket, delete_object.key)
        return JsonResponse({'status': True})

    total_size = 0
    folder_list = [delete_object, ]
    key_list = []
    for folder in folder_list:
        child_list = models.FileRepository.objects.filter(project=request.tracer.project, parent=folder).order_by(
            '-file_type')
        for child in child_list:
            if child.file_type == '2':
                folder_list.append(child)
            else:
                # 文件大小汇总
                total_size += child.filt_size

                # 删除文件
                key_list.append({"key": child.key})
    # cos批量删除文件
    if key_list:
        CosBucket.delete_file_list(request.tracer.project.bucket, key_list)

    # 归还容量
    if total_size:
        request.tracer.project.use_space -= total_size
        request.tracer.project.save()

    # 删除数据库中的文件（级联删除）
    delete_object.delete()
    return JsonResponse({'status': True})


@csrf_exempt
def cos_credential(request, project_id):
    """ 获取cos临时凭证  """
    per_file_limit = request.tracer.price_policy.sfile * 1024 * 1024
    total_file_limit = request.tracer.price_policy.space * 1024 * 1024 * 1024

    file_list = json.loads(request.body.decode('utf-8'))
    print(file_list)
    total_size = 0
    for item in file_list:
        #  文件字节大小 item['size'] = B
        #  单文件限制大小
        if item['size'] > per_file_limit:
            msg = '单文件超出限制（最大：{}M）,文件：{}'.format(request.tracer.price_policy.sfile, item['name'])
            return JsonResponse({'status': False, 'error': msg})
        total_size += item['size']

    # 总容量限制
    # request.tracer.price_policy.space   # 项目允许的空间
    # request.tracer.project.use_space    # 项目已使用的空间
    if request.tracer.project.use_space + total_size > total_file_limit:
        msg = '容量超过限制， 请升级套餐'
        return JsonResponse({'status': False, 'error': msg})

    COS = CosBucket(request.tracer.project.region)
    data_dict = COS.credential(request.tracer.project.bucket)
    print(data_dict)
    return JsonResponse({'status': True, 'data': data_dict})


@csrf_exempt
def file_post(request, project_id):
    """ 已上传成功的文件写入到数据库 """
    print(request.POST)
    getattr()
    return JsonResponse({})

# @csrf_exempt
# def file_post(request, project_id):
#     """ 已上传成功的文件写入到数据 """
#     """
#     name: fileName,
#     key: key,
#     file_size: fileSize,
#     parent: CURRENT_FOLDER_ID,
#     # etag: data.ETag,
#     file_path: data.Location
#     """
#
#     # 根据key再去cos获取文件Etag和"db7c0d83e50474f934fd4ddf059406e5"
#
#     print(request.POST)
#     # 把获取到的数据写入数据库即可
#     form = FileModelForm(request, data=request.POST)
#     if form.is_valid():
#         # 通过ModelForm.save存储到数据库中的数据返回的isntance对象，无法通过get_xx_display获取choice的中文
#         # form.instance.file_type = 1
#         # form.update_user = request.tracer.user
#         # instance = form.save() # 添加成功之后，获取到新添加的那个对象（instance.id,instance.name,instance.file_type,instace.get_file_type_display()
#
#         # 校验通过：数据写入到数据库
#         data_dict = form.cleaned_data
#         data_dict.pop('etag')
#         data_dict.update({'project': request.tracer.project, 'file_type': 1, 'update_user': request.tracer.user})
#         instance = models.FileRepository.objects.create(**data_dict)
#
#         # 项目的已使用空间：更新 (data_dict['file_size'])
#         request.tracer.project.use_space += data_dict['file_size']
#         request.tracer.project.save()
#
#         result = {
#             'id': instance.id,
#             'name': instance.name,
#             'file_size': instance.file_size,
#             'username': instance.update_user.username,
#             'datetime': instance.update_datetime.strftime("%Y年%m月%d日 %H:%M"),
#             'download_url': reverse('file_download', kwargs={"project_id": project_id, 'file_id': instance.id})
#             # 'file_type': instance.get_file_type_display()
#         }
#         return JsonResponse({'status': True, 'data': result})
#
#     return JsonResponse({'status': False, 'data': "文件错误"})
#
#
# def file_download(request, project_id, file_id):
#     """ 下载文件 """
#
#     file_object = models.FileRepository.objects.filter(id=file_id, project_id=project_id).first()
#     res = requests.get(file_object.file_path)
#
#     # 文件分块处理（适用于大文件）     @孙歆尧
#     data = res.iter_content()
#
#     # 设置content_type=application/octet-stream 用于提示下载框        @孙歆尧
#     response = HttpResponse(data, content_type="application/octet-stream")
#     from django.utils.encoding import escape_uri_path
#
#     # 设置响应头：中文件文件名转义      @王洋
#     response['Content-Disposition'] = "attachment; filename={};".format(escape_uri_path(file_object.name))
#     return response
